/*
 * @Author: xiaosihan
 * @Date: 2024-09-23 21:51:29
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2025-01-28 05:05:49
 */

import {
  WebGLRenderer,
  Camera,
  Object3D,
  DepthTexture,
  DepthFormat,
  LinearFilter,
  RGBAFormat,
  UnsignedShortType,
  WebGLRenderTarget,
  Scene,
  Vector2,
  ShaderChunk,
  NoBlending,
  ShaderMaterial,
  AdditiveBlending,
} from "three";
import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass";
import copyShader from "../shaders/copyShader";
import fsQuad from "./fsQuad";

// 选中对象的深度纹理
const selectDepthTexture = (() => {
  const baseDepthTexture = new DepthTexture(4096, 4096);
  baseDepthTexture.format = DepthFormat;
  baseDepthTexture.type = UnsignedShortType;
  baseDepthTexture.anisotropy = 16;
  return baseDepthTexture;
})();

// 选中对象的纹理
const selectTextureTarget = new WebGLRenderTarget(512, 512, {
  minFilter: LinearFilter,
  magFilter: LinearFilter,
  format: RGBAFormat,
  depthTexture: selectDepthTexture,
  anisotropy: 16,
});

// 深度测试后的选中纹理
const selectDethpTestTextureTarget = new WebGLRenderTarget(512, 512, {
  minFilter: LinearFilter,
  magFilter: LinearFilter,
  format: RGBAFormat,
  anisotropy: 16,
});

//深度比对纹理
const depthTestShader = new ShaderMaterial({
  uniforms: {
    map: { value: null }, // 贴图纹理
    baseDepth: { value: null }, // 整个场景的深度纹理
    selectDepth: { value: null }, // 选中的对象深度纹理
  },
  vertexShader: `
        ${ShaderChunk.common}
        ${ShaderChunk.logdepthbuf_pars_vertex}
        varying vec2 vUv;
        void main() {
            vUv = uv;
            gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
            ${ShaderChunk.logdepthbuf_vertex}
        }
    `,
  fragmentShader: `
        ${ShaderChunk.logdepthbuf_pars_fragment}
        uniform sampler2D map;
        uniform sampler2D baseDepth;
        uniform sampler2D selectDepth;
        varying vec2 vUv;
        void main() {
            if(texture2D(baseDepth, vUv).r < texture2D(selectDepth, vUv).r){
                discard;
            }
            if(texture2D(baseDepth, vUv).r == 1.0){
                discard;
            }
            gl_FragColor = texture2D(map, vUv);
            ${ShaderChunk.logdepthbuf_fragment}
        }
    `,
  blending: NoBlending, // 渲染时不与背景融合计算 直接替换
  depthTest: true,
  depthWrite: true,
  transparent: true,
});

const blendMaterial = copyShader.clone();
blendMaterial.blending = AdditiveBlending;

const size = new Vector2();
// 场景对象
const scene = new Scene();

const bloomPass = new UnrealBloomPass( new Vector2( 1024,1024 ), 1.5, 0.4, 0.85 );
// bloomPass.threshold = params.threshold;
// bloomPass.strength = params.strength;
// bloomPass.radius = params.radius;

// 发光后期通道
export default function bloom_pass(
  renderer: WebGLRenderer,
  camera: Camera,
  object3d: Object3D,
  baseRenderTarget: WebGLRenderTarget,
  baseDepthTexture: DepthTexture,
  devicePixelRatio: number
) {
  
  const {
    bloom_enable = false,
    bloom_threshold = 1.5,
    bloom_strength = 0.4,
    bloom_radius = 0.85,
  } = object3d.userData;

  // 不满足条件就不渲染发光效果
  if (!bloom_enable || (bloom_strength === 0) || (bloom_radius === 0)) {
    return;
  }

  bloomPass.threshold = bloom_threshold;
  bloomPass.strength = bloom_strength;
  bloomPass.radius = bloom_radius;

  // 保存原帧缓冲区
  const originRenderTarget = renderer.getRenderTarget();

  // 设置选中目标的帧缓冲区
  renderer.getSize(size);
  size.multiplyScalar(devicePixelRatio);
  bloomPass.setSize(size.x, size.y);
  selectTextureTarget.setSize(size.x, size.y);
  selectDethpTestTextureTarget.setSize(size.x, size.y);

  renderer.setRenderTarget(selectTextureTarget);
  scene.children = [object3d];
  renderer.clear();
  renderer.render(scene, camera);

  //使用深度纹理提取选中的对象未被遮挡的像素点
  renderer.setRenderTarget(selectDethpTestTextureTarget);
  renderer.clear();
  depthTestShader.uniforms.map.value = baseRenderTarget.texture;
  depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
  depthTestShader.uniforms.selectDepth.value = selectDepthTexture;
  fsQuad.render(renderer, depthTestShader);

  // 渲染辉光
  bloomPass.render(renderer, selectDethpTestTextureTarget, selectDethpTestTextureTarget, 0 , false);

  // 将发光效果与原始帧缓冲区混合
  renderer.setRenderTarget(originRenderTarget);
  renderer.clearDepth();
  blendMaterial.uniforms.map.value = selectDethpTestTextureTarget.texture;
  fsQuad.render(renderer,  blendMaterial);

// 调试代码
  // renderer.setRenderTarget(null);
  // renderer.clearDepth();
  // copyShader.uniforms.map.value = blur2TextureTarget.texture;
  // fsQuad.render(renderer, copyShader);
  // return;


}
